﻿/**
* util
* @module util
**/
/**
*	返回xml转换的json字符串<br>
*	<a href="nie.use.html"><font color="red">nie.use模块</font></a>：util.xml2json
*	<br>
*	原作者网站：<a href="http://www.fyneworks.com/jquery/xml-to-json/" target="_blank">http://www.fyneworks.com/jquery/xml-to-json/</a>
*	<pre>
*	&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt;&nbsp;<br />&lt;animals&gt;&nbsp;<br />&lt;dog&nbsp;color='Black'&gt;&nbsp;<br />&lt;name&gt;Rufus&lt;/name&gt;&nbsp;<br />&lt;breed&gt;labrador&lt;/breed&gt;&nbsp;<br />&lt;/dog&gt;&nbsp;<br />&lt;dog&nbsp;breed='whippet'&gt;&nbsp;<br />Adopted&nbsp;<br />&lt;name&gt;Marty&lt;/name&gt;&nbsp;<br />&lt;/dog&gt;&nbsp;<br />&lt;cat&nbsp;color=&quot;White&quot;&gt;&nbsp;<br />&lt;name&gt;Matilda&lt;/name&gt;&nbsp;<br />&lt;/cat&gt;&nbsp;<br />&lt;/animals&gt;&nbsp;
*	<br>
*	$.get('data/animals.xml', function(xml){ 
*	var animals = $.xml2json(xml); 
*	alert(animals.dog[1].name +'/'+ animals.dog[1]); 
*	});
*	</pre>
*	原作者信息：
*	<pre>
*### jQuery XML to JSON Plugin v1.0 - 2008-07-01 ###
* http://www.fyneworks.com/ - diego@fyneworks.com
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
* ###
* Website: http://www.fyneworks.com/jquery/xml-to-json/

* # INSPIRED BY: http://www.terracoder.com/
*           AND: http://www.thomasfrank.se/xml_to_json.html
*
* This simple script converts XML (document of code) into a JSON object. It is the combination of 2
* 'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes.
*	</pre>
*	@namespace $
*	@class xml2json
*	@static
**/
/**
*	@constructor xml2json
*	@param {String} xml xml字符串
*	@return {Object} json
**/
// Avoid collisions
; if (window.jQuery) (function ($) {

    // Add function to jQuery namespace
    $.extend({

        // converts xml documents and xml text to json object
        xml2json: function (xml, extended) {
            if (!xml) return {}; // quick fail

            //### PARSER LIBRARY
            // Core function
            function parseXML(node, simple) {
                if (!node) return null;
                var txt = '', obj = null, att = null;
                var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName);
                var nv = node.text || node.nodeValue || '';
                /*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']);
                if (node.childNodes) {
                    if (node.childNodes.length > 0) {
                        /*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]);
                        $.each(node.childNodes, function (n, cn) {
                            var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName);
                            var cnv = cn.text || cn.nodeValue || '';
                            /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]);
                            if (cnt == 8) {
                                /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']);
                                return; // ignore comment node
                            }
                            else if (cnt == 3 || cnt == 4 || !cnn) {
                                // ignore white-space in between tags
                                if (cnv.match(/^\s+$/)) {
                                    /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']);
                                    return;
                                };
                                /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']);
                                txt += cnv.replace(/^\s+/, '').replace(/\s+$/, '');
                                // make sure we ditch trailing spaces from markup
                            }
                            else {
                                /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']);
                                obj = obj || {};
                                if (obj[cnn]) {
                                    /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']);
                                    if (!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
                                    obj[cnn][obj[cnn].length] = parseXML(cn, true/* simple */);
                                    obj[cnn].length = obj[cnn].length;
                                }
                                else {
                                    /*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']);
                                    obj[cnn] = parseXML(cn);
                                };
                            };
                        });
                    };//node.childNodes.length>0
                };//node.childNodes
                if (node.attributes) {
                    if (node.attributes.length > 0) {
                        /*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes])
                        att = {}; obj = obj || {};
                        $.each(node.attributes, function (a, at) {
                            var atn = jsVar(at.name), atv = at.value;
                            att[atn] = atv;
                            if (obj[atn]) {
                                /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']);
                                if (!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ];
                                obj[atn][obj[atn].length] = atv;
                                obj[atn].length = obj[atn].length;
                            }
                            else {
                                /*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']);
                                obj[atn] = atv;
                            };
                        });
                        //obj['attributes'] = att;
                    };//node.attributes.length>0
                };//node.attributes
                if (obj) {
                    obj = $.extend((txt != '' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/);
                    txt = (obj.text) ? (typeof (obj.text) == 'object' ? obj.text : [obj.text || '']).concat([txt]) : txt;
                    if (txt) obj.text = txt;
                    txt = '';
                };
                var out = obj || txt;
                //console.log([extended, simple, out]);
                if (extended) {
                    if (txt) out = {};//new String(out);
                    txt = out.text || txt || '';
                    if (txt) out.text = txt;
                    if (!simple) out = myArr(out);
                };
                return out;
            };// parseXML
            // Core Function End
            // Utility functions
            var jsVar = function (s) { return String(s || '').replace(/-/g, "_"); };
            var isNum = function (s) { return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); };
            var myArr = function (o) {
                if (!o.length) o = [o]; o.length = o.length;
                // here is where you can attach additional functionality, such as searching and sorting...
                return o;
            };
            // Utility functions End
            //### PARSER LIBRARY END

            // Convert plain text to xml
            if (typeof xml == 'string') xml = $.text2xml(xml);

            // Quick fail if not xml (or if this is a node)
            if (!xml.nodeType) return;
            if (xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;

            // Find xml root node
            var root = (xml.nodeType == 9) ? xml.documentElement : xml;

            // Convert xml to json
            var out = parseXML(root, true /* simple */);

            // Clean-up memory
            xml = null; root = null;

            // Send output
            return out;
        },

        // Convert text to XML DOM
        text2xml: function (str) {
            // NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase
            //return $(xml)[0];
            var out;

            try {
                var doc=new Windows.Data.Xml.Dom.XmlDocument();
                doc.loadXml(str)
                out = doc;
            } catch (e) { throw new Error("Error parsing XML string") };
            return out;
        }
    }); // extend $

})(jQuery);